from pydantic import BaseModel, Field
from typing import Any, Optional, Dict, List
from datetime import datetime


class BaseResponse(BaseModel):
    """Base response model for all API responses."""
    
    success: bool = Field(default=True, description="操作是否成功")
    message: str = Field(default="操作成功", description="响应消息")
    timestamp: datetime = Field(default_factory=datetime.now, description="响应时间戳")
    data: Optional[Any] = Field(default=None, description="响应数据")


class ErrorResponse(BaseResponse):
    """Error response model."""
    
    success: bool = Field(default=False)
    message: str = Field(..., description="错误消息")
    error_code: Optional[str] = Field(default=None, description="错误代码")
    details: Optional[Dict[str, Any]] = Field(default=None, description="错误详情")


class FileUploadResponse(BaseResponse):
    """File upload response model."""
    
    filename: str = Field(..., description="上传的文件名")
    file_size: int = Field(..., description="文件大小（字节）")
    file_type: str = Field(..., description="文件类型")
    extracted_text: Optional[str] = Field(default=None, description="提取的文本内容")


class HealthResponse(BaseModel):
    """Health check response model."""
    
    status: str = Field(default="healthy", description="服务状态")
    version: str = Field(..., description="应用版本")
    timestamp: str = Field(..., description="检查时间")
    components: Optional[Dict[str, str]] = Field(default=None, description="组件状态")


class CoursePoint(BaseModel):
    """课程要点模型."""
    
    title: str = Field(..., description="要点标题")
    description: str = Field(..., description="要点简短描述")
    level: int = Field(..., description="要点级别，1或2")
    sub_points: Optional[list['CoursePoint']] = Field(default=None, description="子要点列表")


class CourseChapter(BaseModel):
    """课程章节模型."""
    
    title: str = Field(..., description="章节标题")
    description: str = Field(..., description="章节简介")
    points: list[CoursePoint] = Field(..., description="章节要点列表")


class KnowledgeNode(BaseModel):
    """知识图谱节点模型."""
    
    id: str = Field(..., description="节点ID")
    title: str = Field(..., description="知识点名称")
    description: str = Field(..., description="知识点描述")
    type: str = Field(..., description="节点类型：concept/skill/application")
    level: int = Field(..., description="知识层级：1-基础，2-中级，3-高级")
    chapter_id: Optional[str] = Field(default=None, description="所属章节ID")


class KnowledgeEdge(BaseModel):
    """知识图谱边模型."""
    
    from_node: str = Field(..., description="源节点ID")
    to_node: str = Field(..., description="目标节点ID")
    relationship: str = Field(..., description="关系类型：prerequisite/includes/applies_to")
    weight: float = Field(default=1.0, description="关系强度")


class KnowledgeGraph(BaseModel):
    """知识图谱模型."""
    
    nodes: List[KnowledgeNode] = Field(..., description="知识节点列表")
    edges: List[KnowledgeEdge] = Field(..., description="知识关系列表")


class LearningPathStep(BaseModel):
    """学习路径步骤模型."""
    
    step_id: str = Field(..., description="步骤ID")
    title: str = Field(..., description="步骤标题")
    description: str = Field(..., description="步骤描述")
    knowledge_nodes: List[str] = Field(..., description="相关知识点ID列表")
    estimated_time: int = Field(..., description="预估学习时间(分钟)")
    difficulty: str = Field(..., description="难度级别：easy/medium/hard")
    prerequisites: List[str] = Field(default=[], description="前置步骤ID列表")


class LearningPath(BaseModel):
    """学习路径模型."""
    
    path_name: str = Field(..., description="学习路径名称")
    description: str = Field(..., description="路径描述")
    target_audience: str = Field(..., description="目标学习者")
    total_time: int = Field(..., description="总学习时间(分钟)")
    steps: List[LearningPathStep] = Field(..., description="学习步骤列表")


class CourseContent(BaseModel):
    """课程内容模型."""
    
    title: str = Field(..., description="课程标题")
    introduction: Optional[str] = Field(default=None, description="课程介绍")
    requirements: Optional[str] = Field(default=None, description="课程须知")
    chapters: list[CourseChapter] = Field(..., description="章节列表")
    knowledge_graph: Optional[KnowledgeGraph] = Field(default=None, description="知识图谱")
    learning_paths: Optional[List[LearningPath]] = Field(default=None, description="推荐学习路径")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")


class ProcessStep(BaseModel):
    """处理步骤详情."""
    
    step_name: str = Field(..., description="步骤名称")
    status: str = Field(..., description="步骤状态：pending/processing/completed/failed")
    progress: int = Field(default=0, description="步骤进度百分比")
    message: str = Field(default="", description="步骤消息")
    details: Optional[Dict[str, Any]] = Field(default=None, description="步骤详细信息")
    start_time: Optional[datetime] = Field(default=None, description="步骤开始时间")
    end_time: Optional[datetime] = Field(default=None, description="步骤结束时间")


class TaskProgress(BaseModel):
    """任务进度详情."""
    
    total_steps: int = Field(..., description="总步骤数")
    current_step: int = Field(default=0, description="当前步骤序号")
    overall_progress: int = Field(default=0, description="总体进度百分比")
    current_step_name: str = Field(default="", description="当前步骤名称")
    current_step_message: str = Field(default="", description="当前步骤消息")
    steps: list[ProcessStep] = Field(default=[], description="所有步骤详情")


class TaskStatus(BaseModel):
    """任务状态模型."""
    
    task_id: str = Field(..., description="任务ID")
    status: str = Field(..., description="任务状态：pending/processing/completed/failed")
    file_info: Optional[Dict[str, Any]] = Field(default=None, description="文件信息")
    progress: TaskProgress = Field(default_factory=lambda: TaskProgress(total_steps=8), description="任务进度详情")
    result: Optional[CourseContent] = Field(default=None, description="解析结果")
    created_at: datetime = Field(default_factory=datetime.now, description="任务创建时间")
    updated_at: datetime = Field(default_factory=datetime.now, description="任务更新时间")
    error_message: Optional[str] = Field(default=None, description="错误信息")


class CourseParseRequest(BaseModel):
    """课程解析请求模型."""
    
    content: Optional[str] = Field(default=None, description="课程相关内容文本")
    file_path: Optional[str] = Field(default=None, description="文件路径")
    
    @staticmethod
    def validate_request(content: Optional[str], file_path: Optional[str]):
        """验证请求参数."""
        if not content and not file_path:
            raise ValueError("必须提供content或file_path中的一个")


class CourseParseResponse(BaseResponse):
    """课程解析响应模型."""

    task_id: str = Field(..., description="任务ID")


class Question(BaseModel):
    """题目模型."""

    id: str = Field(..., description="题目ID")
    title: str = Field(..., description="题目标题", max_length=200)
    content: str = Field(..., description="题目内容", max_length=5000)
    question_type: str = Field(..., description="题目类型：essay/multiple_choice/short_answer", max_length=50)
    subject: str = Field(..., description="学科/科目", max_length=100)
    difficulty: str = Field(default="medium", description="难度级别：easy/medium/hard", max_length=20)
    points: int = Field(default=100, description="总分", ge=1, le=1000)
    tags: List[str] = Field(default=[], description="题目标签")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    updated_at: datetime = Field(default_factory=datetime.now, description="更新时间")


class GradingCriteria(BaseModel):
    """评分标准模型."""

    id: str = Field(..., description="评分标准ID")
    question_id: str = Field(..., description="关联的题目ID")
    criteria_text: str = Field(..., description="评分标准描述", max_length=3000)
    key_points: List[str] = Field(default=[], description="关键得分点")
    deduction_rules: List[str] = Field(default=[], description="扣分规则")
    weight_distribution: Dict[str, float] = Field(default={}, description="权重分配")
    created_at: datetime = Field(default_factory=datetime.now, description="创建时间")
    updated_at: datetime = Field(default_factory=datetime.now, description="更新时间")


class StudentAnswer(BaseModel):
    """学生答案模型."""

    id: str = Field(..., description="答案ID")
    question_id: str = Field(..., description="题目ID")
    student_id: str = Field(..., description="学生ID")
    student_name: str = Field(..., description="学生姓名", max_length=100)
    answer_content: str = Field(..., description="答案内容", max_length=10000)
    submission_time: datetime = Field(default_factory=datetime.now, description="提交时间")


class KeywordMatch(BaseModel):
    """关键词匹配结果."""

    keyword: str = Field(..., description="匹配的关键词")
    position: int = Field(..., description="在答案中的位置")
    context: str = Field(..., description="关键词上下文", max_length=200)
    score_impact: float = Field(..., description="对分数的影响", ge=0, le=100)
    category: str = Field(..., description="关键词类别", max_length=50)


class GradingResult(BaseModel):
    """评分结果模型."""

    id: str = Field(..., description="评分结果ID")
    answer_id: str = Field(..., description="答案ID")
    question_id: str = Field(..., description="题目ID")
    criteria_id: Optional[str] = Field(default=None, description="使用的评分标准ID")

    # 评分结果
    score: float = Field(..., description="得分", ge=0, le=1000)
    max_score: float = Field(..., description="满分", ge=1, le=1000)
    score_percentage: float = Field(..., description="得分百分比", ge=0, le=100)

    # AI分析结果
    keyword_matches: List[KeywordMatch] = Field(default=[], description="关键词匹配结果")
    strengths: List[str] = Field(default=[], description="答案优点")
    weaknesses: List[str] = Field(default=[], description="答案不足")
    suggestions: List[str] = Field(default=[], description="改进建议")

    # 详细评分
    detailed_scores: Dict[str, float] = Field(default={}, description="详细评分项目")
    feedback: str = Field(..., description="评分反馈", max_length=2000)

    # 元信息
    grader_type: str = Field(default="ai", description="评分类型：ai/manual/hybrid")
    confidence: float = Field(default=0.0, description="AI评分置信度", ge=0, le=1)
    grading_time: datetime = Field(default_factory=datetime.now, description="评分时间")
    reviewer_id: Optional[str] = Field(default=None, description="人工审核员ID")
    reviewed_at: Optional[datetime] = Field(default=None, description="人工审核时间")


class GradingRequest(BaseModel):
    """评分请求模型."""

    question_id: str = Field(..., description="题目ID")
    student_answer: str = Field(..., description="学生答案", max_length=10000)
    student_id: Optional[str] = Field(default=None, description="学生ID")
    student_name: Optional[str] = Field(default=None, description="学生姓名", max_length=100)
    grading_criteria: Optional[str] = Field(default=None, description="评分标准（可选）", max_length=3000)
    use_existing_criteria: bool = Field(default=True, description="是否使用已存在的评分标准")
    detailed_feedback: bool = Field(default=True, description="是否生成详细反馈")


class StatelessGradingRequest(BaseModel):
    """无状态评分请求模型."""

    question_title: str = Field(..., description="题目标题", max_length=200)
    question_content: str = Field(..., description="题目内容", max_length=5000)
    student_answer: str = Field(..., description="学生答案", max_length=10000)
    question_type: str = Field(default="essay", description="题目类型")
    subject: str = Field(default="通用", description="学科", max_length=100)
    max_points: int = Field(default=100, description="满分", ge=1, le=1000)
    difficulty: str = Field(default="medium", description="难度等级")
    grading_criteria: Optional[str] = Field(default=None, description="评分标准（可选，不传则使用大模型知识库）", max_length=3000)
    student_id: Optional[str] = Field(default=None, description="学生ID", max_length=50)
    student_name: Optional[str] = Field(default=None, description="学生姓名", max_length=100)
    detailed_feedback: bool = Field(default=True, description="是否生成详细反馈")


class GradingResponse(BaseResponse):
    """评分响应模型."""

    grading_result: GradingResult = Field(..., description="评分结果")


class BatchGradingRequest(BaseModel):
    """批量评分请求模型."""

    question_id: str = Field(..., description="题目ID")
    answers: List[Dict[str, Any]] = Field(..., description="学生答案列表", min_items=1, max_items=100)
    grading_criteria: Optional[str] = Field(default=None, description="评分标准（可选）", max_length=3000)
    use_existing_criteria: bool = Field(default=True, description="是否使用已存在的评分标准")
    detailed_feedback: bool = Field(default=True, description="是否生成详细反馈")


class BatchGradingResponse(BaseResponse):
    """批量评分响应模型."""

    results: List[GradingResult] = Field(..., description="评分结果列表")
    summary: Dict[str, Any] = Field(..., description="评分统计摘要")